
#ifndef __RSP_UPD__HEADER_FILE__
#define __RSP_UPD__HEADER_FILE__


#include "coid/comm/commtypes.h"

////////////////////////////////////////////////////////////////////////////////
struct rsp_settings
{
    uint _ntrailing;                    ///< number of commited frames to keep
    uint _nleading;                     ///< number of frames to wait before commiting


    uint active_slot() const            { return _active_slot; }
    uint active_slot(int k) const       { return (_active_slot + k) & _xcircular; }

    uint active_frame() const           { return _active; }

    
    uint advance_frame()
    {
        ++_active;
        if( ++_active_slot > _xcircular )
            _active_slot = 0;
    }

    void init( uint ntrailing, uint nleading )
    {
        _nleading = nextpow2(nleading);     //because of & _xcircular op.
        DASSERT(_nleading <= 8);            //because we send one byte with command mask

        if(ntrailing)
        {
            //server side
            //we need nwaiting+2, for commands sent from clients for the next frame
            uint n = nextpow2( ntrailing + nleading + 2 );
            _xcircular = n-1;
            _ntrailing = n - _nleading - 2;
        }
        else
        {
            _xcircular = _nleading - 1;
            _ntrailing = _nleading;
        }

        _active_slot = 0;
        _active = 0;
    }

protected:
    uint _xcircular;
    uint _active_slot;
    uint _active;
};


extern rsp_settings&    RSP_SETTINGS;



#define CLASS_NAME(t)       static token class_name()       { static token _T(#t);  return _T; }


#endif //__RSP_UPD__HEADER_FILE__
